#include <iostream>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <map>
#include <list>
#include <queue>

#include "FilterContainer.h"

bool FilterContainer::process()
{
	sleep(1);
	for(BaseFilterListMap::iterator agent_itr = m_filters.begin(); agent_itr != m_filters.end() ; ++agent_itr)
	{
//		std::cout << "checktime=" << agent_itr->first << std::endl;
		//if(difftime(time(0), agent_itr->second->heartbeat_time ) > 2)
		if( ! agent_itr->second->udp_sender_pointer->isActive())
		{
			std::cout << "Agent connection lost=" << agent_itr->first << std::endl;
			erase(agent_itr->first);
		}
		else
		{
			com::Block block;
			block.mutable_frontengineheartbeat();
			agent_itr->second->udp_sender_pointer->sendString(block);

		}

	}
	return true;
}

void FilterContainer::updateSubscriptionContainer(std::string const& agentName)
{
	BaseFilterListMap::iterator itr = m_filters.find(agentName);
	if(itr != m_filters.end())
	{
		itr->second->heartbeat_time = time(0);
	}
}
FilterContainer::FilterContainer() : ThreadProcess("FilterContainer")
{
}

UDPSenderPointer FilterContainer::validate(Frame const& frame)
{
	pthread_mutex_lock(&m_lock);
	for(BaseFilterListMap::iterator agent_itr = m_filters.begin(); agent_itr != m_filters.end() ; ++agent_itr)
		for(BaseFilterList::iterator itr = agent_itr->second->filter_list.begin(); itr != agent_itr->second->filter_list.end() ; ++itr)
		{
			if((*itr)->validate(frame))
			{
				pthread_mutex_unlock(&m_lock);
				return agent_itr->second->udp_sender_pointer;
			}
		}
	pthread_mutex_unlock(&m_lock);
	return UDPSenderPointer();
}
void FilterContainer::addFilter(BaseFilterPointer baseFilter, std::string const& agentName, socketTCP* socket)
{
	pthread_mutex_lock(&m_lock);
	if(baseFilter != BaseFilterPointer())
	{
		BaseFilterListMap::iterator itr = m_filters.find(agentName);
		if(itr == m_filters.end())
		{
			std::cout << "Added filter" << std::endl;
			AgentPointer agent = AgentPointer(new Agent);
			agent->filter_list.push_back(baseFilter);
			agent->heartbeat_time = time(0);
			agent->udp_sender_pointer = socket;
			m_filters[agentName] = agent;
		}
		else
		{
			itr->second->filter_list.push_back(baseFilter);
		}
	}
	pthread_mutex_unlock(&m_lock);
}
void FilterContainer::erase(std::string const& agentName)
{
	pthread_mutex_lock(&m_lock);
	m_filters.erase(agentName);
	pthread_mutex_unlock(&m_lock);
}

